package com.jiang5sx.partnermatching.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jiang5sx.partnermatching.constant.HttpStatus;
import com.jiang5sx.partnermatching.constant.UserConstant;
import com.jiang5sx.partnermatching.domain.User;
import com.jiang5sx.partnermatching.domain.vo.UserVo;
import com.jiang5sx.partnermatching.exception.ServiceException;
import com.jiang5sx.partnermatching.service.UserService;
import com.jiang5sx.partnermatching.mapper.UserMapper;
import com.jiang5sx.partnermatching.utils.PasswordUtil;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.regex.Pattern;
import java.util.stream.Collectors;

/**
 * @author wj
 * @description 针对表【user(用户表)】的数据库操作Service实现
 * @createDate 2024-01-04 21:57:41
 */
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, User>
        implements UserService {

    @Resource
    private UserMapper userMapper;

    /**
     * 用户注册
     *
     * @param account 账号
     * @param password 密码
     * @param checkPassword 校验密码
     * @param planetCode 星球编号
     * @return 结果
     */
    @Override
    public long register(String account, String password, String checkPassword,String planetCode) {
        //账户、密码、校验码非空
        if (StringUtils.isAnyBlank(account, password, checkPassword)) {
            throw new ServiceException("账户、密码、校验码非空可能为空！", HttpStatus.WARN);
        }
        //账户长度不小于4
        if (account.length() < 4) {
            throw new ServiceException("用户账号长度过短！",HttpStatus.WARN);
        }
        //密码长度不小于8
        if (password.length() < 8 || checkPassword.length() < 8) {
            throw new ServiceException("密码长度过短！",HttpStatus.WARN);
        }

        if (planetCode.length() >5 ){
            throw new ServiceException("星球编号过长！",HttpStatus.WARN);
        }

        //账户不能包含特殊字符
        Pattern pattern = Pattern.compile("^[a-zA-Z0-9_]+$");
        if (!pattern.matcher(account).matches()) {
            throw new ServiceException("密码不符合规范！",HttpStatus.WARN);
        }
        //查看密码与校验码是否相同
        if (!password.equals(checkPassword)) {
            throw new ServiceException("用户账号长度过短！",HttpStatus.WARN);
        }

        //账户不能重复,数据库查询
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getAccount, account);
        User user = userMapper.selectOne(wrapper);
        if (user != null) {
            throw new ServiceException("当前账户已注册！",HttpStatus.ERROR);
        }

        //查询星球编号是否唯一
        LambdaQueryWrapper<User> wrapper2 = new LambdaQueryWrapper<>();
        wrapper2.eq(User::getPlanetCode, planetCode);
        User user1 = userMapper.selectOne(wrapper2);
        if (user1 != null) {
            throw new ServiceException("当前星球编号已注册！",HttpStatus.WARN);
        }

        //加密
        String newPassword = PasswordUtil.encrypt(password, PasswordUtil.SALT);
        //插入数据库
        User user2 = new User();
        user2.setAccount(account);
        user2.setPassword(newPassword);
        user2.setPlanetCode(planetCode);
        userMapper.insert(user2);
        return user2.getId();
    }


    /**
     * 登录
     *
     * @param account  账户
     * @param password 密码
     * @param request
     * @return 用户信息
     */
    @Override
    public User login(String account, String password, HttpServletRequest request) {
        //账户、密码、校验码非空
        if (StringUtils.isAnyBlank(account, password)) {
            throw new ServiceException("密码或账户为空！",HttpStatus.ERROR);
        }
        //账户长度不小于4
        if (account.length() < 4) {
            throw new ServiceException("账户长度过短！",HttpStatus.ERROR);
        }
        //密码长度不小于8
        if (password.length() < 8) {
            throw new ServiceException("密码长度过短！",HttpStatus.ERROR);
        }

        //账户不能包含特殊字符
        Pattern pattern = Pattern.compile("^[a-zA-Z0-9_]+$");
        if (!pattern.matcher(account).matches()) {
            throw new ServiceException("账户不能含有特殊字符！！",HttpStatus.ERROR);
        }

        //加密
        String newPassword = PasswordUtil.encrypt(password, PasswordUtil.SALT);

        //查询用户信息
        LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(User::getAccount,account);
        wrapper.eq(User::getPassword,newPassword);
        User user = userMapper.selectOne(wrapper);
        if (user == null){
            throw new ServiceException("账户或密码不正确！",HttpStatus.ERROR);
        }
        //数据脱敏
        User user1 = new User();
        BeanUtils.copyProperties(user,user1,user.getPassword());
        //记录用户信息
        request.getSession().setAttribute(UserConstant.USER_STATUS,user1);
        return user1;
    }

    /**
     * 根据标签查询用户信息
     *
     * @param tagList 标签集合
     * @return 用户信息列表
     */
    @Override
    public List<UserVo> findAllByTags(List<String> tagList) {

        if (CollectionUtils.isEmpty(tagList)){
            throw new ServiceException("标签不存在！");
        }

        List<User> userList = userMapper.findAllByPattern(tagList);


        return  userList
                .stream()
                .map(this::userToUserVo)
                .collect(Collectors.toList());
    }


    /**
     * 返回脱敏后的用户信息
     * @param user 源用户信息
     * @return 脱敏后用户信息
     */
    private UserVo userToUserVo(User user){
        UserVo userVo = new UserVo();
        BeanUtils.copyProperties(user,userVo,user.getPassword());
        return userVo;
    }
}




